iT邦幫忙

2024 iThome 鐵人賽

DAY 18
0
佛心分享-IT 人自學之術

靠近 ASP .NET Core 一點點系列 第 18

Day 18 JWT:ASP.NET Core 驗證機制之一

  • 分享至 

  • xImage
  •  

分享主軸

  • JWT 是什麼 ?
  • JWT 結構
  • ASP .NET Core 內使用 JWT

JWT

  • JSON Web Token 的縮寫,是一種基於 RFC 7519 的開放標準,以 JSON 物件的形式安全傳遞,這些物件可以被驗證和信任,因為它經過數位簽屬

  • 可以使用 HMAC 或使用 RSA 或 ECDSA 等演算法進行簽名

組成結構

可以看成三個部分,以 . 區分,如下範例

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
  • Header
  • Payload
  • Signature

1. Header : 由兩個組成

  • alg : 表示此 Token 使用哪一種加密演算法
  • typ : 表示此 Token 類型,通常為 JWT
{
  "alg": "HS256",
  "typ": "JWT"
}

2. Payload : 可想成是 JWT 內容( 聲明Claim的內容 ),有三種

  • Registered Claims : 標準聲明,可以放,不強制

    iss(Issuer):發行者,JWT 的發行者
    sub(Subject):用戶的唯一標識,通常是所面向的用戶(為了哪個用戶而簽發的)
    aud(Audience):接收者,JWT 的接收者
    exp(Expiration Time):過期時間,JWT 的過期時間
    nbf(Not Before):生效時間,JWT 在此時間之前無效
    iat(Issued At):簽發時間,JWT 的簽發時間
    jti(JWT ID):JWT ID,JWT 的唯一ID,用於防止惡意使用者一直使用

  • Public Claims : 允許自訂義聲明,但避免名稱衝突 (不與 IANA JSON Web Token Registry 內的名稱有衝突 ),可向官方申請自定義的聲明

  • Private Claims : 允許自訂義聲明,不受標準限制 ( 不需要在 IANA JSON Web Token Registry 中註冊 )

小差異

  • 公有聲明是可以由任何使用 JWT 的人自定義的聲明,所以有受限制規範
  • 私有聲明是由共享訊息的雙方自訂義的聲明,所以不受限制規範
{
  "sub": "1234567890",
  "name": "Mars",
  "admin": true
}

3. Signature 簽名 : 用來驗證 JWT 的發送者身份,確保在傳送過程中,未被篡改

解釋 Signature 生成步驟

  1. 編碼 Header 和 Payload

使用 Base64Url 編碼將 Header 和 Payload 轉換為字符串

base64UrlEncode(header) + "." + base64UrlEncode(payload)
  1. 連接編碼後的 Header 和 Payload

將編碼後的 Header 和 Payload 用點(.)連接起來

base64UrlEncode(header) + "." + base64UrlEncode(payload)
  1. 使用密鑰和算法簽名

使用指定的演算法(例如 HMAC SHA256)和密鑰串聯後,進行簽名

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
  1. 生成 Signature

將簽名結果進行 Base64Url 編碼,得到最終的 Signature

base64UrlEncode(HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret))

ASP .NET Core 內實作

簡易範例如下

安裝套件

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

設定檔內

  "JWT": {
    "Key": "YourSecretKeyHereWithAtLeast32Characters",
    "Issuer": "YourIssuer",
    "Audience": "YourAudience"
  }

Program.cs

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = builder.Configuration["JWT:Issuer"],
        ValidAudience = builder.Configuration["JWT:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JWT:Key"]!))
    };
});

呼叫的地方

             var claims = new[]
            {
            new Claim(JwtRegisteredClaimNames.Sub, login.Username),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:Key"]!));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            var token = new JwtSecurityToken(
                issuer: _configuration["JWT:Issuer"],
                audience: _configuration["JWT:Audience"],
                claims: claims,
                expires: DateTime.Now.AddMinutes(30),
                signingCredentials: creds);

            return new JwtSecurityTokenHandler().WriteToken(token);

結果

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJNYXJzIiwianRpIjoiYTVkMjVjMjctMmY1OS00OWMwLWJkNTQtZjMxMDQ3MjMxZDExIiwiZXhwIjoxNzI3NzcxODAwLCJpc3MiOiJZb3VySXNzdWVyIiwiYXVkIjoiWW91ckF1ZGllbmNlIn0.beBeDsY4yCULA3tSXPEEduDKTDkHOiIKZrO1ejzAiVA

產出的 JWT 結構
圖中可以看到上面介紹的三大部分結構,就是 JWT 的組成
https://ithelp.ithome.com.tw/upload/images/20241001/20133954lOMA3nAzi5.png

今日結語
了解如何應用在 ASP .NET Core 內實作 JWT Token,這種方式很常見,比如登入等等,也更了解 JWT 到底是什麼

一步一腳印,慢慢累積程式知識,加油 ~
明天繼續努力!

提供官方網址
https://jwt.io/


上一篇
Day 17 ASP.NET Core Data Protection : 資料保護
下一篇
Day 19 Routing : ASP.NET Core 中的導航
系列文
靠近 ASP .NET Core 一點點27
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言